/**
 * 
 */
package org.stars.util.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.stars.util.StringUtility;

/**
 * Rappresenta un setter.
 * 
 * @author Francesco Benincasa (908099)
 * 
 */
public class Setter extends Accessor {
	
	/**
	 * prefisso dei setter
	 */
	protected static final String	SETTER_PREFIX	= "set";
 
	/**
	 * Dato un metodo restituisce il nome della proprietà associata. Il metodo
	 * deve essere un getter
	 * 
	 * @param metodo
	 * @return nome della proprieta' ricavata dal nome del getter
	 */
	static String getPropertyName(Method metodo) {
		String name = null;
		String nomeMetodo = metodo.getName();

		if (nomeMetodo.startsWith(SETTER_PREFIX) && metodo.getParameterTypes().length == 1 && !metodo.isBridge()) {
			name = nomeMetodo.substring(SETTER_PREFIX.length());
			name = StringUtility.firstLetterLowercase(name);
		}

		return name;
	}

	/**
	 * Prova a creare da un metodo qualsiasi un <code>setter</code>. Nel caso in
	 * cui tale metodo non sia un setter viene restituito <code>null</code>.
	 * 
	 * @param method
	 * @return
	 */
	static Setter getSetter(Method method) {
		Setter ret = null;

		String name = getPropertyName(method);

		if (name != null) {
			ret = new Setter(name, method);
		}
		
		return ret;
	}

	/**
	 * Costruttore.
	 * 
	 * @param propertyName
	 * 			nome della proprietà
	 * @param method
	 * 			metodo setter
	 */
	private Setter(String propertyName, Method method) {
		super(propertyName, method, method.getParameterTypes()[0]);
	}

	/**
	 * Invoca il setter sull'oggetto passato come parametro. Il nuovo
	 * valore della proprietà è il parametro <code>value</code>.
	 * 
	 * @param obj
	 * 		bean da usare
	 * @param value
	 * 		nuovo valore della proprietà
	 * 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public void invoke(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		method.invoke(obj, value);
	}
	
	
}
